home *** CD-ROM | disk | FTP | other *** search
/ The PC-SIG Library 10 / The PC-Sig Library - Shareware for the IBM PC and Compatibles (PC-SIG)(Tenth Edition Disks 1-2804)(1991).iso / PC_SIGCD / 02 / 8 / DISK0285.ZIP / ASMBASIC.TXT < prev    next >
Text File  |  1984-07-11  |  8KB  |  240 lines

  1. File:  ASMBASIC.TXT         On: CLUBware Software Diskette #1
  2. Author: Stan Radzio
  3. Copyright (C) 1984. RAYHAWK AUTOMATION, N W, INC.
  4.  
  5.  
  6. ASMBASIC represents an improved approach for calling assembly
  7. language routines from IBM PC BASIC. The major improvement is that
  8. this approach allows the same source code to be used by both the
  9. BASIC Interpreter and the BASIC Compiler. Hence, you can debug a
  10. program in the more productive interpreter environment and migrate
  11. them easily to the faster executing compiled environment.
  12.  
  13. The published approaches in the magazines make it very difficult to
  14. use the same source to both programs.  These approaches involve
  15. storing routines within BASIC arrays or in high memory beyond the
  16. reaches of the interpreter.  ASMBASIC stores the assembly routines in
  17. low memory below the Basic interpreter.
  18.  
  19. The required subroutines are not loaded with BLOAD or POKE; they are
  20. already resident in memory when the Basic interpreter is invoked.
  21. ASMBASIC is distributed already assembled and linked with eight
  22. assembly language subroutines:
  23.  
  24.     QPRINT - quickly print a string at the current location
  25.     ZPRINT - print a string using the color/attribute given
  26.     SCRLDN - scroll some portion of the screen down
  27.     SCRLUP - scroll some portion of the screen up
  28.     XREP   - repeat some character along the x axis
  29.     YREP   - repeat some character down the y axis
  30.     CLREOL - clear from the current position to the end of the line
  31.     CLREOS - clear from the current position to the end of the screen
  32.  
  33. The source to ASMBASIC is included on the CLUBware diskette so that
  34. these subroutines may be replaced with ones of your own choosing or so
  35. that you may add additional subroutines.
  36.  
  37. The technique is demonstrated in program SUBDEMO.BAS and works like
  38. this:
  39.  
  40. 1) Assemble your utility subroutines.
  41.  
  42. 2) Enter the names of your assembly routines into the subroutine table
  43.    within ASMBASIC.
  44.  
  45. 3) The first name in the table is subroutine 1.
  46.    The second name in the table is subroutine 2.
  47.    Print the table so you won't forget the ordering of names.
  48.  
  49. 4) Assemble ASMBASIC and link it with your assembly language routines.
  50.  
  51. 5) Execute ASMBASIC to make the code resident.    You need only execute
  52.    ASMBASIC once after the system is booted.  However, if you execute
  53.    it more than once, no harm will be done.
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69. File:  ASMBASIC.TXT                        Page 2
  70.  
  71.  
  72.    Review SUBDEMO.BAS.    You will see a method which allows the Basic
  73.    program to determine if it is running compiled or interpreted.
  74.    (The interpreter uses 3 bytes for the string descriptor; the
  75.    compiler uses 4 bytes.  Hence, the difference in the offsets of
  76.    successive elements of a string array is either 3 or 4.) If
  77.    SUBDEMO.BAS is running compiled, it will jump to step 11.
  78.  
  79.    For the steps 6-10, assume you are still developing the code under
  80.    the interpreter.
  81.  
  82.  
  83. 6) Bring up the Basic interpreter.  Load and run a program with code
  84.    equivalent to SUBDEMO.BAS.  This will check for running under the
  85.    interpreter.  Since it is, it will do the following:
  86.  
  87. 7) Poke a two line subroutine into an array:
  88.       INT 67
  89.       RET
  90.    We call this subroutine SUBINIT.  (Note that ASMBASIC services
  91.    interrupt 67.)
  92.  
  93. 8) Call SUBINIT with an argument of 1 to learn the offset of
  94.    subroutine 1 (the first subroutine in the subroutine table).  Call
  95.    SUBINIT with a 2 to learn the offset of subroutine 2, etc.
  96.  
  97.      I% = 1        'We want the offset to the first routine
  98.      CALL  SUBINIT(I%)    'SUBINIT will place the offset into I%
  99.      QPRINT = I%    'Copy the offset into variable QPRINT
  100.  
  101.      I% = 2        'We want the offset to the second routine
  102.      CALL  SUBINIT(I%)    'SUBINIT will place the offset into I%
  103.      SUB2 = I%        'Copy the offset into variable QPRINT
  104.  
  105. 9) After processing all the names in the subroutine table, call
  106.    SUBINIT with an argument of 0 to learn the code segment where
  107.    ASMBASIC has stored your subroutines.
  108.  
  109.      CODESEG% = 0    'To get the Code Segment, use 0 as input.
  110.      CALL  SUBINIT(CODESEG%)    'SUBINIT will return code segment.
  111.  
  112. 10) Use the Basic DEF SEG statement to make your assembly language
  113.    routines callable.
  114.  
  115.      DEF SEG = CODESEG%
  116.  
  117. 11) Call the subroutines wherever and whenever you want:
  118.  
  119.      CALL QPRINT ( FLAG% , MYSTRING$ )
  120.      CALL SUB2( ARG1 , ARG2% , ARG3$ )
  121.  
  122.  
  123.    Since steps 6-10 are skipped during execution of the compiled
  124.    version, the above CALL statements are executed as we desire.
  125.    Under the interpreter, QPRINT and SUB2 are treated as VARIABLES.
  126.  
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135. File:  ASMBASIC.TXT                        Page 3
  136.  
  137.  
  138. Some General Comments
  139.  
  140. An obvious benefit to using ASMBASIC over storing assembly subroutines
  141. in arrays is that the assembly code does not reduce the amount of
  142. memory available for variables and string storage (assuming sufficient
  143. physical memory in the machine).
  144.  
  145. Assembly language programmers will appreciate the ease with which
  146. assembly routines can be debugged.  Link your new subroutine into
  147. ASMBASIC.  Invoke ASMBASIC to make your routine resident.  Bring up
  148. the Basic interpreter under DOS Debug:
  149.  
  150.     DEBUG  BASICA.COM
  151.  
  152. You can find the subroutine table by looking down the interrupt vector
  153. for INT 67h (used to invoke SUBINIT).
  154.  
  155.     -D 00:19C L4
  156.     0000:019C  2C 00 10 06
  157.  
  158. The subroutine table is 2 bytes after the address in the interrupt
  159. vector.  In this example:  0610:002C + 2 = 0610:002E
  160.  
  161. Display the subroutine table.
  162.  
  163.     -D 0610:002E L10
  164.     0610:002E  19 01
  165.     0610:0030  30 01 B0 02 F0 02 D0 04-30 03 70 02 F0 01
  166.  
  167. The eight subroutines in this example can be found at
  168.  
  169.     0610:0119     QPRINT        1
  170.     0610:0130     SCRLDN        2
  171.     0610:02B0     SCRLUP        3
  172.     0610:02F0     XREP        4
  173.     0610:04D0     YREP        5
  174.     0610:0330     CLREOL        6
  175.     0610:0270     CLREOS        7
  176.     0610:01F0     ZPRINT        8
  177.  
  178. Start the interpreter and set breakpoints at the start of the
  179. subroutines you wish to debug:
  180.  
  181.     -G  610:119
  182.  
  183.  
  184. ASMBASIC will not make itself resident more than once after the system
  185. is booted.  If you are modifying and assembling a new subroutine (and
  186. relinking it into ASMBASIC) then you should comment out the:
  187.  
  188.       JMP      SHORT ALREADY_RESIDENT
  189.  
  190. instruction in ASMBASIC so that each execution of ASMBASIC will make
  191. your latest copy of the subroutine available for debugging.
  192.  
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201. File:  ASMBASIC.TXT                        Page 4
  202.  
  203.  
  204. A subtle benefit of ASMBASIC is easy addressability for local data
  205. segments.  In contrast, assembly routines POKE'd or BLOAD'ed into
  206. memory do not have relocation services performed for them.  For
  207. example, the following subroutine will work with ASMBASIC and will
  208. fail if attempted with POKE.
  209.  
  210.     LOCLSEG   SEGMENT
  211.         my local data
  212.     LOCLSEG   ENDS
  213.  
  214.     CODE      SEGMENT PARA PUBLIC 'CODE'
  215.           PUBLIC  MYSUB
  216.           ASSUME  CS:CODE,ES:LOCLSEG
  217.  
  218.     MYSUB      PROC      FAR
  219.           MOV      AX,SEG LOCLSEG
  220.           MOV      ES,AX
  221.           rest of subroutine
  222.     MYSUB      ENDP
  223.  
  224.     CODE      ENDS
  225.           END
  226.  
  227.  
  228. The standard way of allowing routines called by BASIC to have their
  229. own data areas has some undesirable aspects.  First, the code must be
  230. linked /HIGH.  Then, it is loaded by the Debugger (who performs the
  231. relocation needed), BSAVE'ed by the interpreter, then BLOAD'ed into
  232. the exact same location by the interpreter when needed.  There is an
  233. incomplete description of this latter method in the back of the BASIC
  234. manual.  Note that the location occupied by such a BLOAD'ed routine is
  235. the same memory location which will hold BASRUN.EXE if the BASIC code
  236. is ever compiled and executed.
  237.  
  238. For a more reasonable approach, try ASMBASIC.
  239.  
  240.